package com.lifeng.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lifeng.bean.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.UUID;

/**
 * Created by lifeng on 2018/11/21.
 */
@RestController
public class MqProducterController {
    private static final Logger log = LoggerFactory.getLogger(MqProducterController.class);
    /**
     * 用我们自己创建的RabbitTemplate 或者 AmqpTemplate 都是可以的
     * */
    @Autowired
    private AmqpTemplate rabbitTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate1;
    @Autowired
    private ObjectMapper objectMapper;
    /**
     * 给某个队列发消息
     * 发送消息*/
    @RequestMapping("/mqproducter")
    public Object sendMsg(String msg){
        rabbitTemplate.convertAndSend("hello",msg);
        //rabbitTemplate1.convertAndSend("hello",msg);
        return "ok";
    }

    /**
     * 给某个队列发对象消息
     * 发送消息*/
    @RequestMapping("/mqobj")
    public Object sendObjectMsg(String msg){
        User user = new User();
        user.setId(msg);
        user.setNamge(msg);
        user.setBirthday(new Date());
        rabbitTemplate1.setMessageConverter(new Jackson2JsonMessageConverter());
        try {
            //方式1
            /*Message message = MessageBuilder.withBody(objectMapper.writeValueAsBytes(user))
                    .setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT)
                    .build();*/
            //方式2
            //将 user对象转换成json
            String json = "{'id':'张三'}";
            //Message message = new Message(json.getBytes("UTF-8"),new MessageProperties());

            //可以设置消息属性
            MessageProperties properties = new MessageProperties();
            properties.setMessageId(UUID.randomUUID().toString());//消息唯一id
            properties.getHeaders().put("mytoken","1111111111");//设置header
            properties.setContentType("text/plain");//设置消息内容类型
            properties.setExpiration("1000");//设置消息有效期
            properties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);//消息持久化
            Message message = new Message(json.getBytes("UTF-8"),properties);
            //方式3
            //自己转成json字符串，直接将json串发送
            rabbitTemplate1.convertAndSend("helloobj",message);
        }catch (Exception e){
            log.error("消息转换异常",e);
        }

        return "ok";
    }

    /**
     * 给某个队列发消息
     * 采用消息确认机制
     * 发送消息
     */
    @RequestMapping("/mqack")
    public Object sendMsgAck(String msg){
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(UUID.randomUUID().toString());
        rabbitTemplate1.convertAndSend("ackex","hello7", (Object)msg, correlationData);
        return "ok";
    }

    /**
     * 给某个交换机发消息
     * 分发到交换机下所有队列
     * 发送消息*/
    @RequestMapping("/mqtofanoute")
    public Object sendMsgFanoutExchange(String msg){
        /**
         * 参数1:交换机
         * 参数2:队列 路由key 在admin页面配置
         * 交换机fanoutex绑队列hello1 和hello2
         * */
        rabbitTemplate.convertAndSend("fanoutex","",msg);
        return "ok";
    }

    /**
     * 给某个交换机发消息
     * direct模式
     * 通过路由key精确匹配
     * 发送消息*/
    @RequestMapping("/mqtodirectex")
    public Object sendMsgDirectExchange(String msg,String key){
        /**
         * 参数1:交换机
         * 参数2:队列 路由key 在admin页面配置
         * 通过admin页面配的key 转发到队列中，不配key时会转发到所有队列
         * */
        rabbitTemplate.convertAndSend("directex",key,msg);
        return "ok";
    }

    /**
     * 给某个交换机发消息
     * topic模式
     * 通过路由key模糊匹配
     * 发送消息*/
    @RequestMapping("/mqtotopicex")
    public Object sendMsgTopicExchange(String msg,String key){
        /**
         * 参数1:交换机
         * 参数2:队列 路由key 在admin页面配置
         * 通过admin页面配的key 转发到队列中
         * */
        rabbitTemplate.convertAndSend("topicex",key,msg);
        return "ok";
    }

    /**
     * 给某个队列发消息并接受响应信息
     * 发送消息*/
    @RequestMapping("/mqandrecei")
    public Object sendMsgAndRecei(String msg){
        String respon = (String) rabbitTemplate1.convertSendAndReceive("hello8",msg);
        return respon;
    }
}
